package handler

import (
	"net/http"
	"ruoyi-go-echo-ddd/internal/application"
	"ruoyi-go-echo-ddd/internal/domain/model"
	"ruoyi-go-echo-ddd/internal/infrastructure/http/request"
	"ruoyi-go-echo-ddd/internal/infrastructure/http/response"
	"ruoyi-go-echo-ddd/internal/infrastructure/utils"

	"github.com/labstack/echo/v4"
	"github.com/rs/zerolog"
	"github.com/spf13/cast"
)

// SysMenuResourcesHandler 系统菜单资源对应表控制器
type SysMenuResourcesHandler struct {
	App *application.SysMenuResourcesApplication
}

// NewSysMenuResourcesHandler 系统菜单资源对应表控制器初始化
func NewSysMenuResourcesHandler(app *application.SysMenuResourcesApplication) *SysMenuResourcesHandler {
	return &SysMenuResourcesHandler{
		App: app,
	}
}

// SaveHandler 保存
// @Summary 新增菜单资源
// @Description 新增菜单资源
// @Tags 菜单资源管理
// @Accept application/json; charset=UTF-8
// @Produce application/json; charset=UTF-8
// @Security ApiKeyAuth
// @Param param body request.MenuResourcesInsert true "菜单资源"
// @Success 200 {object} response.Result{data=model.SysMenuResources} "新增成功"
// @Failure 400 {object} response.Result "参数解析错误"
// @Failure 500 {object} response.Result "服务器错误"
// @Router /system/menu/resources [post]
func (controller *SysMenuResourcesHandler) SaveHandler(c echo.Context) error {
	//logger := middleware.GetLogger(c)
	var param = new(request.MenuResourcesInsert)
	if err := BindParam(c, param); err != nil {
		zerolog.DefaultContextLogger.Error().Err(err).Msg("系统菜单资源对应表错误")
		response.NewResponse(c, 500, "参数解析错误", nil)
		return err
	}

	if err := c.Validate(param); err != nil {
		return err
	}
	zerolog.DefaultContextLogger.Info().Msgf("系统菜单资源对应表新增入参===\n%s", utils.ToJsonFormat(param))

	result, err := controller.App.Insert(c, request.MenuResourcesInsertConvertModel(param))
	if err != nil {
		response.NewRespCodeErr(c, 500, err)
		return err
	}

	response.NewResponse(c, 200, "新增成功", result)
	return nil
}

// UpdateHandler 更新
// @Summary 更新菜单资源
// @Description 更新菜单资源
// @Tags 菜单资源管理
// @Accept application/json; charset=UTF-8
// @Produce application/json; charset=UTF-8
// @Security ApiKeyAuth
// @Param param body request.MenuResourcesUpdate true "菜单资源"
// @Success 200 {object} response.Result{data=model.SysMenuResources} "更新成功"
// @Failure 400 {object} response.Result "参数解析错误"
// @Failure 500 {object} response.Result "服务器错误"
// @Router /system/menu/resources [put]
func (controller *SysMenuResourcesHandler) UpdateHandler(c echo.Context) error {
	var param = new(request.MenuResourcesUpdate)
	if err := BindParam(c, param); err != nil {
		zerolog.DefaultContextLogger.Error().Err(err).Msg("系统菜单资源对应表更新参数解析错误===")
		response.NewResponse(c, 500, "系统菜单资源对应表更新参数解析错误", nil)
		return err
	}

	zerolog.DefaultContextLogger.Info().Msgf("系统菜单资源对应表更新入参===\n%s", utils.ToJsonFormat(param))

	if err := c.Validate(param); err != nil {
		return err
	}

	result, err := controller.App.Update(c, request.MenuResourcesUpdateConvertModel(param))
	if err != nil {
		response.NewRespCodeErr(c, 500, err)
		return err
	}
	response.NewResponse(c, 200, "修改成功", result)
	return nil
}

// BatchSaveHandler 批量新增
// @Summary 批量新增菜单资源
// @Description 批量新增菜单资源
// @Tags 菜单资源管理
// @Accept application/json; charset=UTF-8
// @Produce application/json; charset=UTF-8
// @Security ApiKeyAuth
// @Param list body []request.MenuResourcesInsert true "菜单资源"
// @Success 200 {object} response.Result{data=[]int64} "新增成功"
// @Failure 400 {object} response.Result "参数解析错误"
// @Failure 500 {object} response.Result "服务器错误"
// @Router /system/menu/resources/batchSave [post]
func (controller *SysMenuResourcesHandler) BatchSaveHandler(c echo.Context) error {
	list := []*request.MenuResourcesInsert{}
	if err := BindParam(c, &list); err != nil {
		zerolog.DefaultContextLogger.Error().Err(err).Msg("系统菜单资源对应表批量新增参数解析错误===")
		response.NewResponse(c, 500, "新增参数解析错误", err)
		return err
	}

	result, err := controller.App.BatchInsert(c, request.MenuResourcesInsertSliceConvertModel(list))
	if err != nil {
		response.NewRespCodeErr(c, 500, err)
		return err
	}

	response.NewResponse(c, 200, "批量新增成功", result)
	return nil
}

type SysMenuResourcesPage struct {
	Content []model.SysMenuResources `json:"content"`
	Records int64                    `json:"records,string"`
	Pages   int64                    `json:"pages,string"`
}

// SelectPageHandler 分页处理
// @Summary 菜单资源分页查询
// @Description 菜单资源分页查询
// @Tags 菜单资源管理
// @Accept application/json; charset=UTF-8
// @Produce application/json; charset=UTF-8
// @Security ApiKeyAuth
// @Param param body request.SysMenuResourcesReq true "分页参数"
// @Success 200 {object} response.Result{data=SysMenuResourcesPage} "查询成功"
// @Failure 500 {object} response.Result "参数解析错误"
// @Router /system/menu/resources/list [post]
func (controller *SysMenuResourcesHandler) SelectPageHandler(c echo.Context) error {
	param := new(request.SysMenuResourcesReq)
	if err := BindParam(c, param); err != nil {
		zerolog.DefaultContextLogger.Error().Err(err).Msg("系统菜单资源对应表分页参数解析错误===")
		response.NewRespCodeMsg(c, http.StatusInternalServerError, "分页参数解析失败")
		return err
	}

	zerolog.DefaultContextLogger.Info().Msgf("系统菜单资源对应表分页查询入参===\n%s", utils.ToJsonFormat(param))

	list, total, page, err := controller.App.SelectPage(c, param)
	if err != nil {
		response.NewResponse(c, 500, err.Error(), nil)
		return err
	}

	pageData := response.NewPageData(list, total, page)

	response.NewResponse(c, 200, "查询成功", pageData)
	return nil
}

// SelectOneHandler 查询单个
// @Summary 菜单资源查询
// @Description 菜单资源查询
// @Tags 菜单资源管理
// @Accept application/json; charset=UTF-8
// @Produce application/json; charset=UTF-8
// @Security ApiKeyAuth
// @Param id path string true "主键ID"
// @Success 200 {object} response.Result{data=model.SysMenuResources} "查询成功"
// @Failure 500 {object} response.Result "参数解析错误"
// @Router /system/menu/resources/{id} [get]
func (controller *SysMenuResourcesHandler) SelectOneHandler(c echo.Context) error {
	id, err := GetSinglePathParam(c, "id")
	if err != nil {
		response.NewRespCodeErr(c, 500, err)
		return err
	}

	data, err := controller.App.SelectById(c, cast.ToInt64(id))
	if err != nil {
		response.NewRespCodeErr(c, 500, err)
		return err
	}

	response.NewResponse(c, 200, "查询成功", data)
	return nil
}

// BatchDeleteHandler 批量删除
// @Summary 菜单资源批量删除
// @Description 菜单资源批量删除
// @Tags 菜单资源管理
// @Accept application/json; charset=UTF-8
// @Produce application/json; charset=UTF-8
// @Security ApiKeyAuth
// @Param id path string true "英文逗号分割的主键ID"
// @Success 200 {object} response.Result{data=int64} "删除成功"
// @Failure 500 {object} response.Result "参数解析错误"
// @Router /system/menu/resources/{id} [delete]
func (controller *SysMenuResourcesHandler) BatchDeleteHandler(c echo.Context) error {
	ids, err := GlobalDeleteHandler(c, "id")
	if err != nil {
		response.NewRespCodeErr(c, 500, err)
		return err
	}

	count, err := controller.App.BatchDelete(c, ids)
	if err != nil {
		response.NewRespCodeErr(c, 500, err)
		return err
	}
	response.NewResponse(c, 200, "删除成功", count)
	return nil
}

// DownloadExcelBufferHandler 导出Excel，使用缓冲流
// @Summary 导出Excel
// @Description 导出Excel-使用缓冲流
// @Tags 菜单资源管理
// @Produce application/vnd.openxmlformats-officedocument.spreadsheetml.sheet, application/json; charset=UTF-8
// @Security ApiKeyAuth
// @Success 200 {file} file "Excel文件"
// @Failure 500 {object} response.Result "参数解析错误"
// @Router /system/menu/resources/export [get]
func (controller *SysMenuResourcesHandler) ExportExcelBufferHandler(c echo.Context) error {
	data, err := controller.App.SelectAllForExcel(c)
	if err != nil {
		response.NewRespCodeErr(c, 500, err)
		return err
	}
	headers := []string{"主键ID", "菜单ID", "请求方式", "请求URL"}
	return DownloadExcelBuffer(c, "菜单资源信息_"+utils.TimeNowFormat("")+".xlsx", "菜单资源", headers, data, true)
}
